home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / iutil / replace.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-02-08  |  6.5 KB  |  296 lines

  1. # include    <ingres.h>
  2. # include    <access.h>
  3. # include    <catalog.h>
  4. # include    <batch.h>
  5. # include    <btree.h>
  6. # include    <sccs.h>
  7.  
  8. SCCSID(@(#)replace.c    8.2    2/8/85)
  9.  
  10. # define    SAMETUP        0
  11. # define    SAMEKEYS    1
  12. # define    DIFFTUP        2
  13.  
  14. /*
  15. **  REPLACE - replace an already existing tuple
  16. **
  17. **    Replace will replace the tuple specified by TID
  18. **    with the new tuple. An attempt is made to not
  19. **    move the tuple if at all possible.
  20. **
  21. **    Three separate conditions are dealt with. If the
  22. **    new tuple is the same as the old tuple, a return 
  23. **    of zero occures and the page is not changed.
  24. **
  25. **    If the keys(if any) are the same and the canonical
  26. **    tuple lengths are the same, then the new tuple will
  27. **    be placed in the same location.
  28. **
  29. **    If the lengths or the keys are different, then the
  30. **    tuple is deleted and the new tuple inserted
  31. **
  32. **    Checkdups specifies whether to check for duplicates.
  33. **    If the new tuple is a duplicate of one already there,
  34. **    then the tuple at TID is deleted
  35. **
  36. **    Returns:
  37. **        <0  fatal error
  38. **         1(DUPTUP)  new tuple was duplicate of returned tid
  39. **         2(DELTUP) tuple identified by tid has been deleted
  40. **         3(BADLID) bad lid
  41. **
  42. **        If replace returns 1 then tid is set to the
  43. **        duplicate tuple. This is necessary for updating
  44. **        secondary indices.
  45. **
  46. **    Trace Flags:
  47. **        24.4-7
  48. */
  49.  
  50.  
  51. replace(d, tid, tuple, checkdups)    
  52. register DESC    *d;
  53. register TID    *tid;
  54. char        *tuple;
  55. int        checkdups;
  56. {
  57.     register int    i;
  58.     int        j;
  59.     char        oldtuple[MAXTUP];
  60.     TID        primtid, tidloc, tidpos;
  61.     long        primpage, old_lid[MAXLID], new_lid[MAXLID], page, t;
  62.     int        need, same, numatts;
  63.     int        len, oldlength;
  64.     char        *new, *old, *oldt;
  65.     char        *getint_tuple();
  66.     char        btree[MAXNAME + 4];
  67.     long        oldtid;
  68.     int        lidwid, compare;
  69.     struct locator    temp;
  70.  
  71. #    ifdef xATR1
  72.     if (tTf(24, 4))
  73.     {
  74.         printf("replace: %.14s,", d->reldum.relid);
  75.         dumptid(tid);
  76.         printf("replace: ");
  77.         printup(d, tuple);
  78.     }
  79. #    endif
  80.  
  81.     /* make tuple canonical */
  82.     need = canonical(d, tuple);
  83.  
  84.     /* if heap or ordered, no dup checking */
  85.     if (abs(d->reldum.relspec) == M_HEAP || d->reldum.reldim > 0)
  86.         checkdups = FALSE;
  87.  
  88.     if (i = get_page(d, tid))
  89.         return (i);    /* fatal error */
  90.  
  91.     /* check if tid exists */
  92.     if (i = invalid(tid))
  93.         return (i);    /* already deleted or invalid */
  94.  
  95.     oldt = getint_tuple(d, tid, oldtuple);
  96.     /* reset page back to main relation page */
  97.     if (i = get_page(d, tid))
  98.         return(i);
  99.     oldlength = tup_len(tid);
  100.     lidwid = LIDSIZE * d->reldum.reldim;
  101.  
  102.     if (d->reldum.reldim > 0)
  103.     {
  104.         /* extract lid values from tuples */
  105.         btreename(d->reldum.relid, btree);
  106.         old = oldt + d->reldum.relwid  - lidwid;
  107.         bmove(old, old_lid, lidwid);
  108.         new = tuple + d->reldum.relwid - lidwid;
  109.         bmove(new, new_lid, lidwid);
  110.         compare = 0;
  111.         for (i = 0; i < d->reldum.reldim; ++i)
  112.         {
  113.             if (new_lid[i] > old_lid[i])
  114.             {
  115.                 compare = 1;
  116.                 break;
  117.             }
  118.             else if (new_lid[i] == old_lid[i])
  119.                 compare = -1;
  120.             else
  121.             {
  122.                 compare = 0;
  123.                 break;
  124.             }
  125.         }
  126.         if (compare >= 0)
  127.         {
  128.         /* do insertion and deletion of new lid and old values in
  129.         ** order that insures that they will be placed in the proper
  130.         ** place
  131.         */
  132.             if (compare == 1)
  133.             {
  134.                 if (insert_mbtree(d, btree, new_lid, tid, &tidpos) < 0)
  135.                     return(BADLID);
  136.                 if (fwrite(old_lid, 1, lidwid, Del_infp) != lidwid)
  137.                     syserr("write error in replace");
  138.                 ++Del_cnt;
  139.             }
  140.             else if (compare == 0)
  141.             {
  142.                 page = RT;
  143.                 for (j = 0; j < d->reldum.reldim; ++j)
  144.                 {
  145.                     if (new_lid[j] > 0 && (t = get_tid(page, new_lid[j], &temp)) > 0)
  146.                         page = t;
  147.                     else if (t == -1)
  148.                     {
  149.                         for (i = j + 1; i < d->reldum.reldim; ++i)
  150.                         {
  151.                             if (new_lid[i] != 1 && new_lid[i] != 0)
  152.                                 return(BADLID);
  153.                         }
  154.                         break;
  155.                     }
  156.                     else if (new_lid[j] == 0)
  157.                     {
  158.                         for (i = j + 1; i < d->reldum.reldim; ++i)
  159.                         {
  160.                             if (new_lid[i] != 0)
  161.                                 return(BADLID);
  162.                         }
  163.                         break;
  164.                     }
  165.                     else
  166.                         return(BADLID);
  167.                 }
  168.                 for (i = 0; i < d->reldum.reldim; ++i)
  169.                     if (new_lid[i] < 0)
  170.                         return(BADLID);
  171.                 delete_btree(old_lid, d->reldum.reldim);
  172.                 if (insert_mbtree(d, btree, new_lid, tid, &tidpos) < 0)
  173.                     return(BADLID);
  174.             }
  175.         }
  176.     }
  177.  
  178.     /* check whether tuples are the same, different lengths, different keys */
  179.     same = DIFFTUP;    /* assume diff lengths or keys */
  180.     if (oldlength == need)
  181.     {
  182.         /* same size. check for same domains */
  183.         same = SAMETUP;    /* assume identical */
  184.         new = tuple;
  185.         old = oldt;
  186.         /* ignore lid field */
  187.         numatts = d->reldum.relatts - d->reldum.reldim;
  188.         for (i = 1; i <= numatts; i++)
  189.         {
  190.             len = d->relfrml[i] & I1MASK;
  191.             if (icompare(new, old, d->relfrmt[i], len))
  192.             {
  193.                 if (d->relxtra[i])
  194.                 {
  195.                     same = DIFFTUP;
  196.                     break;
  197.                 }
  198.                 same = SAMEKEYS;
  199.             }
  200.             old += len;
  201.             new += len;
  202.         }
  203.     }
  204.  
  205. #    ifdef xATR2
  206.     if (tTf(24, 5))
  207.         printf("replace:same=%d\n", same);
  208. #    endif
  209.  
  210.     switch (same)
  211.     {
  212.  
  213.       case SAMETUP:
  214.         /* new tuple same as old tuple */
  215.         i = DUPTUP;    /* flag as duplicate */
  216.         /* though character strings may compare equal,
  217.         **  they can look different, so if they do look different
  218.         **  go ahead and do the replace using put_tuple.  */
  219.         if (!bequal(tuple, oldt, d->reldum.relwid - lidwid))
  220.             goto puttuple;
  221.         break;
  222.  
  223.       case SAMEKEYS:
  224.         /* keys the same, lengths the same, tuples different */
  225.         if (checkdups)
  226.         {
  227.             /* This is either an ISAM or HASH file. If mainpg
  228.             ** is non-zero, then the primary page=mainpg -1.
  229.             ** Otherwise, "find" must be called to determine
  230.             ** the primary page
  231.             */
  232.             if (Acc_head->mainpg)
  233.             {
  234.                 primpage = Acc_head->mainpg -1;
  235.                 stuff_page(&primtid, &primpage);
  236.             }
  237.             else
  238.             {
  239.                 if (i = find(d, FULLKEY, &primtid, &primtid, tuple))
  240.                     return (i);    /* fatal error */
  241.                 if (i = get_page(d, tid))    /* restore page for tuple */
  242.                     return (i);
  243.             }
  244.     
  245.             if (i = scan_dups(d, &primtid, tuple))
  246.             {
  247.                 if (i == DUPTUP)
  248.                 {
  249.                     del_tuple(tid, oldlength);    /* tuple a duplicate */
  250.                     d->reladds--;
  251.                     /* copy tid of duplicate tuple */
  252.                     bmove(&primtid, tid, sizeof(primtid));
  253.                 }
  254.                 break;
  255.             }
  256.         }
  257.         goto puttuple;
  258.  
  259.       case DIFFTUP:
  260.         /* keys different or lengths different */
  261.         get_page(d, tid);
  262.         del_tuple(tid, oldlength);
  263.         bmove(tid, &oldtid, LIDSIZE);
  264.  
  265.         /* find where to put tuple */
  266.         if (i = findbest(d, tid, tuple, need, checkdups))
  267.         {
  268.             d->reladds--;
  269.             break;
  270.         }
  271.  
  272.         /* place new tuple in page */
  273.     puttuple:
  274.         put_tuple(tid, Acctuple, need);
  275.         i = NEWTUP;
  276.  
  277.         if (same == DIFFTUP && d->reldum.reldim > 0)
  278.         {
  279.             /* main tid value has changed, update btree */
  280.             if (compare < 0)
  281.                 search_btree(oldtid, &tidpos);
  282.             /* tid different, must be reflected in BTree */
  283.                 replace_btree(*tid, &tidpos);
  284.         }
  285.     }
  286.  
  287. #    ifdef xATR1
  288.     if (tTf(24, 6))
  289.     {
  290.         printf("replace rets %d,", i);
  291.         dumptid(tid);
  292.     }
  293. #    endif
  294.     return (i);
  295. }
  296.